<?php
declare(strict_types=1);

namespace app\common\business;

use app\common\model\AttributeValue as AttributeValueModel;
use app\common\model\Category as CategoryModel;
use app\common\model\RelationAttributeCategory as RelationAttributeCategoryModel;
use app\common\model\Module as ModuleModel;
use Exception;

class AttributeValue extends CommonBase
{
    private $_attributeValueObj = null;

    public function __construct(string $websiteCode)
    {
        $this->_attributeValueObj = new AttributeValueModel([], $websiteCode);
        $this->_websiteCode       = $websiteCode;
    }

    public function getAllAttributeValue(array $where = []): array
    {
        $rows = [];
        try {
            $rows = $this->_attributeValueObj->getAllAttributeValue($where);
        } catch (Exception $e) {
            logErr('读取所有属性值失败', sprintf('websiteCode:%s,method:%s,err:%s', $this->_websiteCode, __METHOD__, $e->getMessage()));
        }

        return $rows;
    }

    public function getAttributeValueList(int $page = 1, int $limit = 10, array $where = []): array
    {
        $res   = [];
        $count = 0;
        try {
            $res   = $this->_attributeValueObj->getAttributeValueList($page, $limit, $where);
            $count = $this->_attributeValueObj->getAttributeValueCount($where);
        } catch (Exception $e) {
            logErr('读取属性值列表失败', sprintf('websiteCode:%s,method:%s,err:%s', $this->_websiteCode, __METHOD__, $e->getMessage()));
        }

        $rows = $res->toArray();


        return ['rows' => $rows, 'count' => $count];
    }

    public function addAttributeValue(array $data): array
    {
        try {
            return [self::_RESULT => $this->_attributeValueObj->addAttributeValue($data), self::_MESSAGE => self::_ADD_SUCCESS_MESSAGE];
        } catch (Exception $e) {
            logErr('添加属性值失败', sprintf('websiteCode:%s,method:%s,err:%s', $this->_websiteCode, __METHOD__, $e->getMessage()));
        }

        return [self::_RESULT => false, self::_MESSAGE => self::_SYSTEM_ERROR_MESSAGE];
    }

    public function findAttributeValueById(int $id): array
    {
        $attributeValue = [];
        try {
            $attributeValue = $this->_attributeValueObj->findAttributeValueById($id);
        } catch (Exception $e) {
            logErr('通过主键读取属性值详细信息失败', sprintf('websiteCode:%s,method:%s,err:%s', $this->_websiteCode, __METHOD__, $e->getMessage()));
        }

        return $attributeValue;
    }

    public function updateAttributeValue(int $id, array $data): array
    {
        try {
            return [self::_RESULT => $this->_attributeValueObj->updateAttributeValue($id, $data), self::_MESSAGE => self::_UPDATE_SUCCESS_MESSAGE];
        } catch (Exception $e) {
            logErr('通过主键更新属性值失败', sprintf('websiteCode:%s,method:%s,err:%s', $this->_websiteCode, __METHOD__, $e->getMessage()));
        }

        return [self::_RESULT => false, self::_MESSAGE => self::_SYSTEM_ERROR_MESSAGE];
    }

    public function deleteAttributeValue(int $id): array
    {
        try {
            if ($this->_checkAttributeValueIsUsed($id)) {
                return [self::_RESULT => false, self::_MESSAGE => sprintf(self::_DELETE_ATTRIBUTE_VALUE_IS_USED_ERROR, '')];
            }

            return [self::_RESULT => $this->_attributeValueObj->deleteAttributeValue($id), self::_MESSAGE => self::_DELETE_SUCCESS_MESSAGE];
        } catch (Exception $e) {
            logErr('删除属性值失败', sprintf('websiteCode:%s,method:%s,err:%s', $this->_websiteCode, __METHOD__, $e->getMessage()));
        }

        return [self::_RESULT => false, self::_MESSAGE => self::_SYSTEM_ERROR_MESSAGE];
    }

    public function clearAttributeValueCache(): bool
    {
        return $this->_attributeValueObj->clearAttributeValueCache();
    }

    private function _checkAttributeValueIsUsed(int $id): bool
    {
        $attributeValueOne = $this->_attributeValueObj->findAttributeValueById($id);
        if (empty($attributeValueOne)) {
            return false;
        }

        $attributeValue = $attributeValueOne->toArray();

        $relationAttributeCategoryModel = new RelationAttributeCategoryModel([], $this->_websiteCode);
        $relationAttributeCategoryObj   = $relationAttributeCategoryModel->getAllRelationAttributeCategoryByAttributeId($attributeValue['attribute_id']);
        $relationAttributeCategories    = $relationAttributeCategoryObj->toArray();
        if (empty($relationAttributeCategories)) {
            return false;
        }

        $categoryIds = [];
        foreach ($relationAttributeCategories as $category) {
            $categoryIds[] = $category['category_id'];
        }
        $categoryModel = new CategoryModel([], $this->_websiteCode);
        $categoryObj   = $categoryModel->getAllCategoryByIds($categoryIds);
        $categories    = $categoryObj->toArray();
        if (empty($categories)) {
            return false;
        }

        $moduleIds = [];
        foreach ($categories as $category) {
            if (!in_array($category['module_id'], $moduleIds)) {
                $moduleIds[] = $category['module_id'];
            }
        }
        $moduleModel = new ModuleModel([], $this->_websiteCode);
        $moduleObj   = $moduleModel->getAllModuleByIds($moduleIds);
        $modules     = $moduleObj->toArray();
        if (empty($modules)) {
            return false;
        }

        $moduleCodes = [];
        foreach ($modules as $module) {
            $moduleCodes [] = $module['code'];
        }

        return $this->_attributeValueObj->checkAttributeValueIsUsed($moduleCodes, $id);
    }

    public function batchDeleteAttributeValue(array $ids): array
    {
        try {
            $failedIds = [];
            foreach ($ids as $id) {
                if ($this->_checkAttributeValueIsUsed($id)) {
                    $failedIds[] = $id;
                }
            }

            if (count($failedIds)) {
                return [self::_RESULT => false, self::_MESSAGE => sprintf(self::_DELETE_ATTRIBUTE_VALUE_IS_USED_ERROR, '属性值 ID:' . implode(',', $failedIds))];
            }

            return [self::_RESULT => $this->_attributeValueObj->batchDeleteAttributeValue($ids), self::_MESSAGE => self::_DELETE_SUCCESS_MESSAGE];
        } catch (Exception $e) {
            logErr('通过主键批量删除属性值失败', sprintf('websiteCode:%s,method:%s,err:%s', $this->_websiteCode, __METHOD__, $e->getMessage()));
        }

        return [self::_RESULT => false, self::_MESSAGE => self::_SYSTEM_ERROR_MESSAGE];
    }
}
